package com.t.bricks.bussiness.service.userandright.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.t.bricks.bussiness.db.dao.userandright.UserAndRightDao;
import com.t.bricks.bussiness.db.entity.userandright.SimpleRight;
import com.t.bricks.bussiness.service.userandright.UserAndRightService;
import com.t.bricks.model.Log;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.utils.function.data.CachePool;
import com.t.bricks.utils.function.data.CacheTxtUtil;
import com.t.bricks.utils.function.file.FileUtil;
import com.t.bricks.utils.spring.ModuleUtil;

/**
 * 用户权限表'UserAndRight表'基本业务操作类接口实现
 */
@Service
public class UserAndRightServiceImpl implements UserAndRightService {
	
	@Autowired
	private UserAndRightDao userAndRightDao;
	
	/**
	 * 缓存文件夹路径
	 */
	private static String sCacheFilePath = String.format("%s/temp/cache/UserAndRight/",
			System.getProperty("user.dir").replaceAll("\\\\", "/"));
	
	/**
	 * 用户权限验证用缓存池(普通)
	 */
	private static CachePool<List<String>> cUserRightCacheOrdinary = new CachePool<List<String>>();
	
	/**
	 * 用户权限验证用缓存池(特殊)
	 */
	private static CachePool<List<String>> cUserRightCacheSpecial = new CachePool<List<String>>();
	
	//----------------------------- 自动生成代码结束 -----------------------------//

	/**
	 * 根据用户取权限标识字符串(一个权限标识代表了多个可访问的url路径)
	 * @param sUserId
	 * @return
	 */
	@Override
	public MsgEmity findEnglishByUserId(String sUserId) {
		if (null == sUserId || "".equals(sUserId.trim())) {
			return new MsgEmity(false, "参数用户编号为空", 8001);
		}
		
		List<String> list = CacheTxtUtil.readCacheFile(String.format("%s%s_Englist.txt", sCacheFilePath, sUserId));
		if (null == list || list.size() < 1) {
			MsgEmity me = loadRight(sUserId);//读取指定用户的权限
			if (!me.isSuccess()) {
				return me;
			}
			
			list = CacheTxtUtil.readCacheFile(String.format("%s%s_Englist.txt", sCacheFilePath, sUserId));
		}
		
		if (null == list || list.size() < 1) {
			return new MsgEmity(false, "没有找到用户对应的权限", 8002);
		}
		
		return new MsgEmity(true, "查询成功", list.get(0));
	}
	
	/**
	 * 验证指定用户是否有访问指定url的权限
	 * @param sUserId 验证的用户
	 * @param url 请求验证的权限(URL地址)
	 * @return
	 */
	@Override
	public MsgEmity checkRight(String sUserId, String url) {
		if (null == sUserId || "".equals(sUserId.trim())) {
			return new MsgEmity(false, "待验证的用户编号为空", 8001);
		}

		if (null == url || "".equals(url.trim())) {
			return new MsgEmity(false, "待验证的访问权限为空", 8002);
		}
		
		String urlOrdinary = String.format(";%s;", url.trim());//添加前后缀以免误判
		
		//--先判断普通权限,普通权限的前后都加有';'--//
		List<String> list = cUserRightCacheOrdinary.findData(sUserId);
		if (null == list || list.size() < 2) {
			list = CacheTxtUtil.readCacheFile(String.class, String.format("%s%s_UrlOrdinary.txt", sCacheFilePath, sUserId));
			if (null == list || list.size() < 1) {
				MsgEmity me = loadRight(sUserId);//读取指定用户的权限
				if (!me.isSuccess()) {
					return me;
				}
				list = CacheTxtUtil.readCacheFile(String.class, String.format("%s%s_UrlOrdinary.txt", sCacheFilePath, sUserId));
			}
			
			cUserRightCacheOrdinary.add(sUserId, list);
		}
		
		if (null != list && list.contains(urlOrdinary)) {
			return new MsgEmity(true, "有权限", 8999);
		}

		//--普通权限没有则查找通配符方式,通配符方式权限的前后没有加';'--//
		list = cUserRightCacheSpecial.findData(sUserId);
		if (null == list || list.size() < 2) {
			list = CacheTxtUtil.readCacheFile(String.class, String.format("%s%s_UrlSpecial.txt", sCacheFilePath, sUserId));
			cUserRightCacheSpecial.add(sUserId, list);
		}
		
		if (null == list) {
			return MsgEmity.err(8003, "无权权访问:", url);
		}
		
		for (String string : list) {
			if (url.indexOf(string) == 0) {//当前请求URL以'通配符URL'开头则说明有权限
				return new MsgEmity(true, "有权限", 8999);
			}
		}

		return MsgEmity.err(8004, "无权权访问:", url);
	}
	
	/**
	 * 读取指定用户的权限,并返回权限集合
	 * @param sUserId
	 * @return
	 */
	private MsgEmity loadRight(String sUserId) {
		List<SimpleRight> result = null;
		
		//--读文件获取--//
		String filePath = String.format("%s%s_Simpl.txt", sCacheFilePath, sUserId);
		result = CacheTxtUtil.readCacheFile(SimpleRight.class, filePath);
		if (null != result && result.size() > 0) {
			crateRightCache(result, sUserId);
			return new MsgEmity(true, "在文件中找到", result);//返回结果
		}
		
		//--文件没有则读库获取--//
		result = userAndRightDao.findRightListByInit(sUserId);//根据用户读取用户对应的所有权限,注意:只返回了3个值sRightId/sEnglish/sControllerPath
		if (null == result || result.size() < 1) {
			return new MsgEmity(false, "未查询到用户相关权限信息!", 8100);
		}
		
		crateRightCache(result, sUserId);
		
		CacheTxtUtil.createCacheFile(result, String.format("%s%s_Simpl.txt", sCacheFilePath, sUserId));//写入文件，以便下次不用读库
		
		return new MsgEmity(true, "在数据库中找到", result);//返回结果
	}
	
	/**
	 * 创建指定用户的权限缓存,并返回权限集合
	 * @param list
	 * @param sUserId
	 * @return
	 */
	private MsgEmity crateRightCache(List<SimpleRight> list, String sUserId) {
		if (null == list || list.size() < 1) {
			return new MsgEmity(false, "数据有错", 8100);
		}

		StringBuilder sb = new StringBuilder(100);
		StringBuilder sbEnglist = new StringBuilder(3000);
		List<String> listRightId = new ArrayList<String>(list.size());
		List<String> listUrlsOrdinary = new ArrayList<String>(list.size() * 2);
		List<String> listUrlsSpecial = new ArrayList<String>(list.size() * 2);
		for (SimpleRight simpleRight : list) {
			sbEnglist.append(simpleRight.getsEnglish()).append("/");
			listRightId.add(simpleRight.getsRightId());
			
			String temp = simpleRight.getsControllerPath();
			if (null == temp || "".equals(temp)) {
				continue;
			}
			
			String[] str = temp.split(";");
			for (String string : str) {
				if ("".equals(string.trim()) || "-".equals(string.trim())) {
					continue;
				}
				
				sb.setLength(0);
				sb.append(";").append(string).append(";");
				if (!string.contains("*") && !listUrlsOrdinary.contains(sb.toString())) {
					listUrlsOrdinary.add(sb.toString());
					continue;
				}
				
				if (string.contains("*") && !listUrlsSpecial.contains(string)) {
					listUrlsSpecial.add(string.replace("*", ""));
					continue;
				}
			}
		}

		CacheTxtUtil.createCacheFile(listUrlsOrdinary, String.format("%s%s_UrlOrdinary.txt", sCacheFilePath, sUserId));//写入文件，以便下次不用读库
		CacheTxtUtil.createCacheFile(listUrlsSpecial, String.format("%s%s_UrlSpecial.txt", sCacheFilePath, sUserId));//写入文件，以便下次不用读库
		CacheTxtUtil.createCacheFile(sbEnglist.toString(), String.format("%s%s_Englist.txt", sCacheFilePath, sUserId));//写入文件，以便下次不用读库
		CacheTxtUtil.createCacheFile(listRightId, String.format("%s%s_UserRightIdList.txt", sCacheFilePath, sUserId));//写入文件，以便下次不用读库
		
		return new MsgEmity(true, "创建缓存成功", 8999);//返回结果
	}
	
	/**
	 * 添加权限信息
	 * @param sUserId
	 * @param sRightList
	 * @return
	 */
	@Override
	public MsgEmity add(String sUserId, String sRightList) {
		if (null == sUserId || "".equals(sUserId.trim())) {
			return new MsgEmity(false, "用户编号不能为空！", 8001);
		}

		String currentLoginUserId = ModuleUtil.currentLoginUserId();//取当前登录用户编号
		MsgEmity me = userAndRightDao.add(sUserId, sRightList, currentLoginUserId);
		if (!me.isSuccess()) {
			return me;
		}

		clearCache(sUserId);//删除缓存指定用户权限集合，因为角色的权限已经改变，对应的用户权限也会改变，必须进行缓存重构
		
		return me;
	}

//	/**
//	 * 根据用户取权限
//	 * @param sLoginUserId
//	 * @return
//	 */
//	@Override
//	public MsgEmity findByUser(String sLoginUserId) {
//		if (null == sLoginUserId) {
//			return new MsgEmity(false, "用户编号不能为空！", 8001);
//		}
//		
//		sLoginUserId = sLoginUserId.trim();
//		
//		//--从缓存文件读取数据--//
//		List<UserRightInfo> list = null;
//		if (null == isDisableTxtCache || !isDisableTxtCache) {
//			String filePath = String.format("%s%s_Simpl.txt", sCacheFilePath, sLoginUserId.trim());
//			list = CacheTxtUtil.readCacheFile(UserRightInfo.class, filePath);//读取预存储的缓存文件
//		}
//
//		boolean isReadDb = false;
//		StringBuilder sbEnglist = null;
//		StringBuilder sbControllerPath = null;
//		List<String> listRightId = null;
//		if (null == list || list.size() < 1) {
//			MsgEmity me = userAndRightDao.findRightInfoByUser(sLoginUserId);
//			if (!me.isSuccess()) {
//				return me;
//			}
//
//			List<UserRightInfo> temp = me.getData();
//			isReadDb = true;
//			
//			//--构造上下级数据,从数据库中已经按sPid进行过排序--//
//			list = new ArrayList<UserRightInfo>();
//			listRightId = new ArrayList<String>(temp.size());
//			sbEnglist = new StringBuilder(3000);
//			sbControllerPath = new StringBuilder(3000);
//			
//			for (int i = 0; i < temp.size(); i++) {
//				UserRightInfo userRightInfo = temp.get(i);
//				sbEnglist.append(userRightInfo.getsEnglish()).append(",");
//				sbControllerPath.append(userRightInfo.getsControllerPath()).append("/");
//				listRightId.add(userRightInfo.getsRightId());
//				
//				for (int n = i+1; n < temp.size(); n++) {//上一个数据不用再检查
//					if (userRightInfo.getsId().equals(temp.get(n).getsPid())) {
//						userRightInfo.getChild().add(temp.get(n));
//					}
//				}
//				
//				if ("00".equals(userRightInfo.getsPid())) {
//					list.add(userRightInfo);//一级节点则加入
//				}
//			}
//		}
//		
//		if (null == list || list.size() < 1) {
//			return new MsgEmity(false, "获取树形数据信息为空！", 8002);
//		}
//		
//		if (isReadDb && (null == isDisableTxtCache || !isDisableTxtCache)) {//重新读取了数据库并且使用Txt缓存
//			CacheTxtUtil.createCacheFile(list, String.format("%s%s_Simpl.txt", sCacheFilePath, sLoginUserId));//写入文件，以便下次不用读库
//			CacheTxtUtil.createCacheFile(sbEnglist.toString(), String.format("%s%s_Englist.txt", sCacheFilePath, sLoginUserId));//写入文件，以便下次不用读库
//			CacheTxtUtil.createCacheFile(sbControllerPath.toString(), String.format("%s%s_Url.txt", sCacheFilePath, sLoginUserId));//写入文件，以便下次不用读库
//			CacheTxtUtil.createCacheFile(listRightId, String.format("%s%s_UserRightIdList.txt", sCacheFilePath, sLoginUserId));//写入文件，以便下次不用读库
//		}
//		
//		return new MsgEmity(true, "查询成功！", list);
//	}
	
	/**
	 * 删除权限信息
	 * @param sUserId
	 * @return
	 */
	@Override
	public MsgEmity del(String sUserId) {
		if (null == sUserId || "".equals(sUserId.trim())) {
			return new MsgEmity(false, "编号不能为空！", 8005);
		}
		
		MsgEmity me = userAndRightDao.del(sUserId);
		if (!me.isSuccess()) {
			return me;
		}
		
		clearCache(sUserId);//清理指定用户的缓存
		
		return me;
	}
	
	/**
	 * 清理指定用户的缓存
	 * @param sUserId 用户编号
	 * @return
	 */
	@Override
	public MsgEmity clearCache(String sUserId) {
		if (null == sUserId || "".equals(sUserId.trim())) {
			cUserRightCacheOrdinary.freeAll();//清理所有缓存
			cUserRightCacheSpecial.freeAll();//清理所有缓存
			
			if (FileUtil.delDir(sCacheFilePath)) {
				return MsgEmity.success(8999, "删除所有用户的'关联权限信息'缓存成功！");
			}
			
			if (new File(sCacheFilePath).exists()) {
				return MsgEmity.err(8002, "试图删除所有用户的'关联权限信息'缓存失败！");
			}
			
			return MsgEmity.success(8999, "请求删除所有用户的'关联权限信息'缓存成功！");
		}
		
		sUserId = sUserId.trim();

		cUserRightCacheOrdinary.free(sUserId);//清理指定用户缓存
		cUserRightCacheSpecial.free(sUserId);//清理指定用户缓存
		
		String filePath = String.format("%s%s_Simpl.txt", sCacheFilePath, sUserId);
		FileUtil.delFile(filePath);
		if (!new File(filePath).exists()) {
			Log.error("试图删除用户的'关联权限信息'缓存失败！");
			return MsgEmity.err(8003, "试图删除用户的'关联权限信息'缓存失败！");
		}
		
		filePath = String.format("%s%s_Englist.txt", sCacheFilePath, sUserId);
		FileUtil.delFile(filePath);
		if (!new File(filePath).exists()) {
			Log.error("试图删除用户的'关联权限信息标识'缓存失败！");
			return MsgEmity.err(8004, "试图删除用户的'关联权限信息'缓存失败！");
		}
		
		filePath = String.format("%s%s_UrlOrdinary.txt", sCacheFilePath, sUserId);
		FileUtil.delFile(filePath);
		if (!new File(filePath).exists()) {
			Log.error("试图删除用户的'关联权限信息路径'缓存失败！");
			return MsgEmity.err(8005, "试图删除用户的'关联权限信息'缓存失败！");
		}
		
		filePath = String.format("%s%s_UrlSpecial.txt", sCacheFilePath, sUserId);
		FileUtil.delFile(filePath);
		if (!new File(filePath).exists()) {
			Log.error("试图删除用户的'关联权限信息路径'缓存失败！");
			return MsgEmity.err(8005, "试图删除用户的'关联权限信息'缓存失败！");
		}

//		filePath = String.format("%s%s_Tree.txt", sCacheFilePath, sUserId);
//		FileUtil.delFile(filePath);
//		if (new File(filePath).exists()) {
//			Log.error("试图删除用户的'关联权限树形信息'缓存失败！");
//			return MsgEmity.err(8006, "试图删除用户的'关联权限树形信息'缓存失败！");
//		}
		
		return MsgEmity.success(8999, "请求删除用户的'关联权限信息'缓存成功！");
	}
	
	/**
	 * 根据用户查询用户所拥有的权限编号集合
	 * @param sUserId
	 * @return
	 */
	@Override
	public MsgEmity findRightId(String sUserId) {
		if (null == sUserId || "".equals(sUserId.trim())) {
			return new MsgEmity(false, "用户编号不能为空！", 8001);
		}
		
		String filePath = String.format("%s%s_UserRightIdList.txt", sCacheFilePath, sUserId);
		
		List<String> list = CacheTxtUtil.readCacheFile(String.class, filePath);//读取预存储的缓存文件
		if (null != list && list.size() > 0) {
			return MsgEmity.success(list, "查询成功");
		}
	
		if (null == list || list.size() < 1) {
			MsgEmity me = loadRight(sUserId);//读取指定用户的权限
			if (!me.isSuccess()) {
				return me;
			}
			
			list = CacheTxtUtil.readCacheFile(String.class, filePath);
		}
				
		return MsgEmity.success(list, "查询成功");
	}

	/**
	 * 根据用户查询用户所拥有的权限的最后更新时间
	 * @param sUserId
	 * @return
	 */
	@Override
	public MsgEmity lastTime(String sUserId) {
		if (null == sUserId || "".equals(sUserId.trim())) {
			return new MsgEmity(false, "待验证的用户编号为空", 8001);
		}
		
		String filePath = String.format("%s%s_Simpl.txt", sCacheFilePath, sUserId);
		File file = new File(filePath);
		if (file.exists()) {
			return new MsgEmity(true, "查询到权限信息缓存最后时间", file.lastModified());
		}

		loadRight(sUserId);//建立缓存
		
		file = new File(filePath);//再查一遍
		if (file.exists()) {
			return new MsgEmity(true, "查询到权限信息缓存最后时间", file.lastModified());
		}
		
		return new MsgEmity(false, "没有查询到权限信息缓存最后时间", 8002);
	}
	
}
